package cn.org.rookie.jeesdp.file.service;

import cn.org.rookie.jeesdp.core.BusinessException;
import cn.org.rookie.jeesdp.core.mongodb.QueryBuilder;
import cn.org.rookie.jeesdp.core.utils.IOUtils;
import com.mongodb.client.gridfs.model.GridFSFile;
import lombok.extern.slf4j.Slf4j;
import org.bson.Document;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.gridfs.GridFsResource;
import org.springframework.data.mongodb.gridfs.GridFsTemplate;
import org.springframework.data.mongodb.gridfs.GridFsUpload;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import org.springframework.util.StopWatch;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

@Slf4j
@Service
public class FileService {

    @Autowired
    public GridFsTemplate gridFsTemplate;

    public String store(InputStream in, String fileName, String contentType) {
        try {
            ByteArrayInputStream bais = new ByteArrayInputStream(in.readAllBytes());
            bais.mark(bais.available());
            String md5 = DigestUtils.md5DigestAsHex(bais);
            bais.reset();
            GridFSFile file = gridFsTemplate.findOne(QueryBuilder.where("metadata.MD5", md5).build());
            if (file == null || file.getLength() == 0) {
                StopWatch watch = new StopWatch();
                watch.start();
                String id = gridFsTemplate.store(
                        GridFsUpload.fromStream(bais)
                                .filename(fileName)
                                .contentType(contentType)
                                .chunkSize(16000000)
                                .metadata(new Document("MD5", md5))
                                .build()
                ).toHexString();
                IOUtils.close(bais, in);
                watch.stop();
                log.debug("文件：{}，上传成功！耗时：{}秒", fileName, watch.getTotalTimeSeconds());
                return id;
            } else {
                log.debug("文件：{}，已存在！MD5：{}", fileName, md5);
                return file.getObjectId().toHexString();
            }

        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public void delete(String id) {
        gridFsTemplate.delete(QueryBuilder.where("_id", id).build());
    }

    public GridFsResource getResource(String id, String fileName) {
        return gridFsTemplate.getResource(gridFsTemplate.findOne(QueryBuilder.where("_id", id).and("filename", fileName).build()));
    }

    public GridFsResource getResource(String id) {
        return getResource(id, null);
    }

    public InputStream getInputStream(String id, String fileName) {
        try {
            return getResource(id, fileName).getInputStream();
        } catch (IOException e) {
            throw new BusinessException(0, e);
        }
    }

    public InputStream getInputStream(String id) {
        return getInputStream(id, null);
    }
}
